package com.jamlu.framework.network;

import android.support.annotation.NonNull;
import android.util.Log;

import com.google.gson.GsonBuilder;
import com.jamlu.framework.network.converter.FormGsonConverterFactory;
import com.jamlu.framework.utils.helper.NullStringToEmptyAdapterFactory;

import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

import okhttp3.CacheControl;
import okhttp3.Headers;
import okhttp3.Interceptor;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import okhttp3.ResponseBody;
import okio.Buffer;
import okio.BufferedSource;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;

/**
 * 目前没有处理多请求体的情况，可能会出现问题(未知)
 * Created by DMing on 2018/3/7.
 */

public class NetworkManager {
    private static Retrofit mRetrofit;
    private static boolean isDebug = true;//是否输出日志
    private static final String TAG = "request";
    public static final Charset UTF8 = Charset.forName("UTF-8");
    private static OkHttpClient okHttpClient;
    //(en:英文；cn：中文；hk：繁体)
    public final static String EN = "en";
    public final static String CN = "cn";
    public final static String HK = "hk";
    public static String language = CN;


    public static Retrofit getInstance(@NonNull String baseUrl,boolean isDebug) {
        NetworkManager.isDebug = isDebug;
        if (mRetrofit == null) {
            mRetrofit = new Retrofit.Builder()
                    .baseUrl(baseUrl)
                    .client(getOkHttpClient())
                    .addConverterFactory(FormGsonConverterFactory.create(new GsonBuilder().registerTypeAdapterFactory(new NullStringToEmptyAdapterFactory()).create()))
//                    .addConverterFactory(GsonConverterFactory.create(new GsonBuilder().registerTypeAdapterFactory(new NullStringToEmptyAdapterFactory()).create()))
                    .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                    .build();
            return mRetrofit;
        } else {
            return mRetrofit;
        }
    }

    public static OkHttpClient getOkHttpClient() {
        if (okHttpClient == null) {
            OkHttpClient.Builder httpClientBuilder = new OkHttpClient.Builder();
            httpClientBuilder.addInterceptor(new Interceptor() {
                @Override
                public Response intercept(@NonNull Chain chain) throws IOException {
                    Request request = chain.request();
                    if (com.blankj.utilcode.util.NetworkUtils.isConnected()) {
                        return chain.proceed(request);
                    } else {
                        throw new NoNetworkException(); //无网络直接返回
                    }
                }

            });
            httpClientBuilder.addInterceptor(new Interceptor() {
                @Override
                public Response intercept(@NonNull Chain chain) throws IOException {
                    Request request = chain.request()
                            .newBuilder()
                            .addHeader("Accept", "application/vnd.api.v1+json;q=0.9,*/*;q=0.8")
                            .addHeader("Accept-Language", language)//(en:英文；cn：中文；hk：繁体)
                            .build();
                    return chain.proceed(request);
                }
            });
            if (isDebug) {
                httpClientBuilder.addInterceptor(new Interceptor() {
                    @Override
                    public Response intercept(@NonNull Chain chain) throws IOException {
                        Request request = chain.request();
                        String requestStartMessage = "--> " + request.method() + ' ' + request.url();
                        Log.e(TAG, requestStartMessage);
//                        Headers headers = request.headers();
//                        for (int i = 0, count = headers.size(); i < count; i++) {
//                            String name = headers.name(i);
//                            // Skip headers from the request body as they are explicitly logged above.
////                            if (!"Content-Type".equalsIgnoreCase(name) && !"Content-Length".equalsIgnoreCase(name)) {
//                                Log.e(TAG,name + ": " + headers.value(i));
////                            }
//                        }
                        RequestBody requestBody = request.body();
                        boolean hasRequestBody = requestBody != null;
                        if (hasRequestBody && requestBody.contentLength() != -1) {
                            Buffer buffer = new Buffer();
                            requestBody.writeTo(buffer);
                            Log.e(TAG, "{ " + buffer.readString(UTF8).replace("&", " ") + " }");
//                            Log.e(TAG, "--> END " + request.method() + " (" + requestBody.contentLength() + "-byte body)");
//                        } else {
//                            Log.e(TAG, "--> END " + request.method());
                        }
                        //////////////////返回/////////////////////////////
                        long startNs = System.nanoTime();
                        Response response;
                        try {
                            response = chain.proceed(request);
                        } catch (Exception e) {
                            Log.e(TAG, "<-- HTTP FAILED: " + e);
                            throw e;
                        }
                        long tookMs = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startNs);
                        ResponseBody responseBody = response.body();
                        if (responseBody != null) {
                            Log.e(TAG, "<-- " + response.code() + ' ' + response.message() + ' '
                                    + response.request().url() + " (" + tookMs + "ms" + ')');
                            BufferedSource source = responseBody.source();
                            source.request(Long.MAX_VALUE); // Buffer the entire body.
                            Buffer buffer = source.buffer();
                            Log.e(TAG, buffer.clone().readString(UTF8));
//                            Log.e(TAG, "<-- END HTTP (" + buffer.size() + "-byte body)");
                        } else {
                            Log.e(TAG, "<-- HTTP FAILED: ResponseBody is Null");
                        }
                        return response;
                    }
                });
            }
            okHttpClient = httpClientBuilder.build();
        }
        return okHttpClient;
    }


    public static List<MultipartBody.Part> filesToMultipartBody(List<File> files) {
        return filesToMultipartBody(files, null);
    }

    public static List<MultipartBody.Part> filesToMultipartBody(List<File> files, Map<String, String> params) {
        MultipartBody.Builder builder = new MultipartBody.Builder()
                .setType(MultipartBody.FORM);

        for (int i = 0; i < files.size(); i++) {
            File file = files.get(i);
            if (file != null) {
                String name = file.getName();
                RequestBody requestBody = null;
                if (name.endsWith(".png") || name.endsWith(".jpg")) {
//                    Bitmap bitmap = decodeSampledBitmapFromFile(file,200,200);
                    //Bitmap zipImage = ImageUtils.compressBySampleSize(bitmap, 6, true);
                    try {
//                        if (name.endsWith(".png")) {
//                            requestBody = RequestBody.create(MediaType.parse("image/*"), ImageUtils.bitmap2Bytes(bitmap, Bitmap.CompressFormat.PNG));
//                        } else {
//                            requestBody = RequestBody.create(MediaType.parse("image/*"), ImageUtils.bitmap2Bytes(bitmap, Bitmap.CompressFormat.JPEG));
//                        }
                        if (name.endsWith(".png")) {
                            requestBody = RequestBody.create(MediaType.parse("image/*"), file);
                        } else {
                            requestBody = RequestBody.create(MediaType.parse("image/*"), file);
                        }
//                        bitmap.recycle();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                } else {
                    requestBody = RequestBody.create(MediaType.parse("multipart/form-data"), file);
                }
                if (requestBody != null) {
                    builder.addFormDataPart("file", file.getName(), requestBody);
                }
            }
        }
        if (params != null) {
            Set<Map.Entry<String, String>> entries = params.entrySet();
            for (Map.Entry<String, String> entry : entries) {
                builder.addFormDataPart(entry.getKey(), entry.getValue());
            }
        }
        return builder.build().parts();
    }

    public static List<MultipartBody.Part> fileToMultipartBody(File file, Map<String, String> params) {
        MultipartBody.Builder builder = new MultipartBody.Builder()
                .setType(MultipartBody.FORM);

        if (file != null) {
            String name = file.getName();
            RequestBody requestBody = null;
            if (name.endsWith(".png") || name.endsWith(".jpg")) {
//                    Bitmap bitmap = decodeSampledBitmapFromFile(file,200,200);
                //Bitmap zipImage = ImageUtils.compressBySampleSize(bitmap, 6, true);
                try {
//                        if (name.endsWith(".png")) {
//                            requestBody = RequestBody.create(MediaType.parse("image/*"), ImageUtils.bitmap2Bytes(bitmap, Bitmap.CompressFormat.PNG));
//                        } else {
//                            requestBody = RequestBody.create(MediaType.parse("image/*"), ImageUtils.bitmap2Bytes(bitmap, Bitmap.CompressFormat.JPEG));
//                        }
//                        bitmap.recycle();
                    if (name.endsWith(".png")) {
                        requestBody = RequestBody.create(MediaType.parse("image/*"), file);
                    } else {
                        requestBody = RequestBody.create(MediaType.parse("image/*"), file);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            } else {
                requestBody = RequestBody.create(MediaType.parse("multipart/form-data"), file);
            }
            if (requestBody != null) {
                builder.addFormDataPart("file", file.getName(), requestBody);
            }
        }
        if (params != null) {
            Set<Map.Entry<String, String>> entries = params.entrySet();
            for (Map.Entry<String, String> entry : entries) {
                builder.addFormDataPart(entry.getKey(), entry.getValue());
            }
        }
        return builder.build().parts();
    }
}
